﻿using Foxit.PDF;
using Foxit.PDF.IO;
using Foxit.PDF.PageElements;
using System;
using System.Globalization;

namespace Sustainalytics.Reporting.Framework
{
    public class PercentileBullet : PageElement
    {
        public float Left { get; set; }
        public float Top { get; set; }
        public float Radius { get; set; }
        public int Value { get; set; }
        public Font ValueFont { get; set; }
        public float ValueFontSize { get; set; }

        private const string NaN = "N/A";
        private const int NoValue = -1;

        public static string OrdinalNumberSuffix(int number)
        {
            var suffix = string.Empty;

            if (number < 1)
                return suffix;

            var ones = number % 10;
            var tens = (int)Math.Floor(number / 10f) % 10;

            if (tens == 1)
            {
                suffix = "th";
            }
            else
            {
                switch (ones)
                {
                    case 1:
                        suffix = "st";
                        break;

                    case 2:
                        suffix = "nd";
                        break;

                    case 3:
                        suffix = "rd";
                        break;

                    default:
                        suffix = "th";
                        break;
                }
            }

            return suffix;
        }

        private Group Elements()
        {
            const float borderWidth = 0.1f;

            var elements = new Group();
            
            elements.Add(
                new Circle(Left + Radius, Top + Radius, Radius, Colors.YellowBulletColor, Colors.YellowBulletColor, borderWidth, LineStyle.Solid));

            var labelWidth = Radius * 2;
            var lebelHeigth = ValueFontSize + 2f;
            var labelTopOffset = (Radius * 2 - ValueFontSize) / 2 + 1f;

            var leftOffset = 0.0f;
            var topOffset = 0.0f;
            var suffixOffset = 28f;

            var valueColor = RgbColor.White;
            var valueFontSize = ValueFontSize;
            var percentile = Value;

            if (percentile == 0)
            {
                leftOffset = 0f;
                topOffset = 2f;
            }

            if (percentile == 100)
            {
                valueFontSize = ValueFontSize - 8f;
                leftOffset = -2f;
                topOffset = 5f;
                suffixOffset += 2f;
            }

            if (percentile > 0 && percentile < 10)
            {
                valueFontSize = ValueFontSize + 2f;
                leftOffset = -2f;
                suffixOffset = 25f;
            }

            if (percentile >= 10 && percentile < 100)
            {
                valueFontSize = ValueFontSize - 2f;
                leftOffset = -3f;
                topOffset = 2f;
            }

            if (Value <= NoValue)
            {
                valueFontSize = ValueFontSize - 6f;

                elements.Add(new Label(NaN,
                  Left + leftOffset, Top + labelTopOffset + 4f, labelWidth, lebelHeigth, ValueFont, valueFontSize, TextAlign.Center, valueColor));
            }
            else
            {
                elements.Add(
              new Label(Value.ToString(CultureInfo.InvariantCulture),
                  Left + leftOffset, Top + labelTopOffset + topOffset, labelWidth, lebelHeigth, ValueFont, valueFontSize, TextAlign.Center, valueColor));

                elements.Add(
                    new Label(OrdinalNumberSuffix(Value),
                        Left + leftOffset + suffixOffset, Top + labelTopOffset + 2f, 20f, 9f, ValueFont, 7, TextAlign.Left, valueColor));
            }

            return elements;
        }

        public override void Draw(PageWriter writer)
        {
            var elements = Elements();

            writer.Write_q_(true);
            elements.Draw(writer);
            writer.Write_Q(true);
        }
    }
}
